<template>
  <span class="animated-number">{{ displayValue }}</span>
</template>

<script>
export default {
  name: 'AnimatedNumber',
  props: {
    value: {
      type: [Number, String],
      required: true,
      default: 0
    },
    duration: {
      type: Number,
      default: 2000 // 动画持续时间(毫秒)
    },
    format: {
      type: Boolean,
      default: true // 是否添加千位分隔符
    }
  },
  data() {
    return {
      displayValue: 0,
      animationFrame: null
    }
  },
  watch: {
    value(newVal, oldVal) {
      this.animate(oldVal, newVal)
    }
  },
  mounted() {
    this.displayValue = this.formatNumber(this.value)
  },
  beforeDestroy() {
    cancelAnimationFrame(this.animationFrame)
  },
  methods: {
    animate(start, end) {
      const startTime = performance.now()
      const duration = this.duration
      
      const updateValue = (timestamp) => {
        const elapsed = timestamp - startTime
        const progress = Math.min(elapsed / duration, 1)
        const currentValue = start + (end - start) * this.easeOutQuad(progress)
        
        this.displayValue = this.formatNumber(Math.floor(currentValue))
        
        if (progress < 1) {
          this.animationFrame = requestAnimationFrame(updateValue)
        } else {
          this.displayValue = this.formatNumber(end)
        }
      }
      
      this.animationFrame = requestAnimationFrame(updateValue)
    },
    
    // 缓动函数 - 使动画更自然
    easeOutQuad(t) {
      return t * (2 - t)
    },
    
    // 数字格式化（添加千位分隔符）
    formatNumber(num) {
      if (!this.format) return num
      return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
    }
  }
}
</script>

<style scoped>
.animated-number {
  font-family: Arial, sans-serif;
  font-size: 24px;
  font-weight: bold;
  color: #fff;
}
</style>